home *** CD-ROM | disk | FTP | other *** search
- From: decvax!wanginst!perlman
- Date: Sun, 2 Jun 85 16:35:35 edt
- Subject: improved version of shar (shell archiver)
-
- Here is a new version of my C shar program.
- I have made some changes in how existing files are handled;
- now shar will not overwrite existing files.
- I have worked with lint and prof to improve the code,
- especially the speed. You can try it out for yourself.
-
- Gary Perlman Wang Institute Tyngsboro, MA 01879 (617) 649-9731
- UUCP: decvax!wanginst!perlman CSNET: perlman@wanginst
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # shar.1
- # shar.c
- # traverse.3
- # traverse.c
- # getopt.3
- # getopt.c
- # Makefile
- # This archive created: Tue Jun 4 01:07:18 1985
- # By: Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'shar.1'" '(2691 characters)'
- if test -f 'shar.1'
- then
- echo shar: will not over-write existing file "'shar.1'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'shar.1'
- X.TH SHAR 1net "June 3, 1985" "UNIX User's Manual" "Wang Institute"
- X.SH NAME
- Xshar \- create file storage archive for extraction by /bin/sh
- X.SH SYNOPSIS
- X.B shar
- X[-abcsv] [-d delim] [-p prefix] files
- X.SH DESCRIPTION
- X.I shar
- Xprints its input files with special command lines around them
- Xto be used by the shell,
- X.I /bin/sh ,
- Xto extract them later.
- XThe output can be filtered through the shell to
- Xrecreate copies of the original files.
- X.PP
- X.I shar
- Xallows directories to be named, and
- X.I shar
- Xprints the necessary commands
- X.ul
- X(mkdir & cd)
- Xto create new directories and fill them.
- X.I shar
- Xwill emit commands to make executable plain files executable.
- X.I shar will not allow existing files to be over-written;
- Xsuch files must be removed by the file extractor.
- X.SH OPTIONS
- X.de OP
- X.TP
- X.B -\\$1
- X..
- X.OP a
- XAll the options.
- XThe options:
- X.B "-v -c -b -p <tab>X"
- Xare implied.
- X.OP s
- XSilent running.
- XAll checking and extra output is inhibited.
- X.OP v
- XPrint verbose feedback messages about what
- X.I shar
- Xis doing to be printed during extraction.
- XSizes of plain files are echoed to allow a simple validity check.
- X.OP c
- XCheck file size on extraction by counting characters.
- XAn error message is reported to the person doing the
- Xextraction if the sizes don't match.
- XOne reason why the sizes may not match is that
- X.I shar
- Xwill append a newline to complete incomplete last lines;
- X.I shar
- Xprints a message that mentions added newlines.
- XAnother reason why the sizes may not match is that some
- Xnetwork mail programs remove non-whitespace control characters.
- X.I shar
- Xprints a message that mentions control characters to the extractor.
- X.OP b
- XExtract files into basenames so that files with absolute path names
- Xare put into the current directory.
- XThis option has strange effects when directories are archived.
- X.OP d delim
- XUse this as the ``end of file'' delimiter instead of the default.
- XThe only reason to change it is if you suspect an file
- Xcontains the default delimiter:
- X.B SHAR_EOF.
- X.OP p prefix
- XUse this as the prefix to each line of the archived files.
- XThis is to make sure that special characters at the start of lines are not
- Xeaten up by programs like mailers.
- XIf this option is used,
- Xthe files will be extracted with the stream editor
- X.B sed
- Xrather than
- X.B cat
- Xso it is more efficient and portable to avoid setting the prefix,
- Xthough perhaps less safe if you don't know what is in the files.
- X.SH "SEE ALSO
- Xtar(1), cpio(1), tp(1), sh(1)
- X.SH AUTHOR
- XGary Perlman
- X(based on a shell version by James Gosling,
- Xwith additions motivated by
- XDerek Zahn,
- XMichael Thompson,
- XH. Morrow Long,
- XFred Avolio,
- XGran Uddeborg,
- X&
- XChuck Wegrzyn)
- X.SH LIMITATIONS
- X.I shar
- Xdoes not know anything about
- Xlinks between files
- Xor binary files.
- SHAR_EOF
- if test 2691 -ne "`wc -c < 'shar.1'`"
- then
- echo shar: error transmitting "'shar.1'" '(should have been 2691 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'shar.c'" '(8881 characters)'
- if test -f 'shar.c'
- then
- echo shar: will not over-write existing file "'shar.c'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'shar.c'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <ctype.h>
- X
- X/*{
- XShar puts readable text files together in a package
- Xfrom which they are easy to extract. The original version
- Xwas a shell script posted to the net, shown below:
- X #Date: Mon Oct 18 11:08:34 1982
- X #From: decvax!microsof!uw-beave!jim (James Gosling at CMU)
- X AR=$1
- X shift
- X for i do
- X echo a - $i
- X echo "echo x - $i" >>$AR
- X echo "cat >$i <<'!Funky!Stuff!'" >>$AR
- X cat $i >>$AR
- X echo "!Funky!Stuff!" >>$AR
- X done
- XI rewrote this version in C to provide better diagnostics
- Xand to run faster. The major difference is that my version
- Xdoes not affect any files because it prints to the standard
- Xoutput. Mine also has several options.
- X
- XGary Perlman/Wang Institute/Tyngsboro, MA/01879/(617) 649-9731
- X
- XMany enhancements motivated by Michael Thompson.
- X
- XDirectory archiving motivated by Derek Zahn @ wisconsin
- X His version had some problems, so I wrote a general
- X routine for traversing a directory hierarchy. It
- X allows marching through a directory on old and new
- X UNIX systems.
- X}*/
- X
- X/* COMMANDS */
- X#define EXTRACT "#! /bin/sh" /* magic exec string at shar file start */
- X#define PATH "/bin:$PATH" /* search path for programs */
- X#define CAT "cat"; /* /bin/cat */
- X#define SED "sed 's/^%s//'" /* /bin/sed removes Prefix from lines */
- X#define MKDIR "mkdir" /* make a new dirctory */
- X#define CHMOD "chmod +x" /* change file protection (for executables) */
- X#define CHDIR "cd" /* change current directory */
- X#define TEST "test" /* /bin/test files */
- X#define WC_C "wc -c <" /* counts chars in file */
- X#define ECHO "echo shar" /* echo a message to extractor */
- X
- Xmain (argc, argv) char **argv;
- X {
- X int shar ();
- X int optind;
- X if ((optind = initial (argc, argv)) < 0)
- X exit (1);
- X if (header (argc, argv, optind))
- X exit (2);
- X while (optind < argc)
- X traverse (argv[optind++], shar);
- X footer ();
- X exit (0);
- X }
- X
- X/* OPTIONS */
- Xtypedef int lgl;
- X#define true ((lgl) 1)
- X#define false ((lgl) 0)
- Xint Lastchar; /* the last character printed */
- Xint Ctrlcount; /* how many bad control characters are in file */
- X
- X#define USAGE "[-abcsv] [-p prefix] [-d delim] files > archive"
- X#define OPTSTRING "abcsvp:d:"
- X
- Xlgl Verbose = false; /* provide append/extract feedback */
- Xlgl Basename = false; /* extract into basenames */
- Xlgl Count = false; /* count characters to check transfer */
- Xlgl Silent = false; /* turn off all verbosity */
- Xchar *Delim = "SHAR_EOF"; /* put after each file */
- Xchar Filter[100] = CAT; /* used to extract archived files */
- Xchar *Prefix = NULL; /* line prefix to avoid funny chars */
- X
- Xint /* returns the index of the first operand file */
- Xinitial (argc, argv) char **argv;
- X {
- X int errflg = 0;
- X extern int optind;
- X extern char *optarg;
- X int C;
- X while ((C = getopt (argc, argv, OPTSTRING)) != EOF)
- X switch (C)
- X {
- X case 'v': Verbose = true; break;
- X case 'c': Count = true; break;
- X case 'b': Basename = true; break;
- X case 'd': Delim = optarg; break;
- X case 's': /* silent running */
- X Silent = true;
- X Verbose = false;
- X Count = false;
- X Prefix = NULL;
- X break;
- X case 'a': /* all the options */
- X Verbose = true;
- X Count = true;
- X Basename = true;
- X /* fall through to set prefix */
- X optarg = " X";
- X case 'p': (void) sprintf (Filter, SED, Prefix = optarg); break;
- X default: errflg++;
- X }
- X if (errflg || optind == argc)
- X {
- X if (optind == argc)
- X fprintf (stderr, "shar: No input files\n");
- X fprintf (stderr, "USAGE: shar %s\n", USAGE);
- X return (-1);
- X }
- X return (optind);
- X }
- X
- Xheader (argc, argv, optind)
- Xchar **argv;
- X {
- X int i;
- X lgl problems = false;
- X long clock;
- X char *ctime ();
- X char *getenv ();
- X char *NAME = getenv ("NAME");
- X char *ORG = getenv ("ORGANIZATION");
- X for (i = optind; i < argc; i++)
- X if (access (argv[i], 4)) /* check read permission */
- X {
- X fprintf (stderr, "shar: Can't read '%s'\n", argv[i]);
- X problems++;
- X }
- X if (problems) return (problems);
- X /* I have given up on putting a cut line in the archive.
- X Too many people complained about having to remove it.
- X puts ("-----cut here-----cut here-----cut here-----cut here-----");
- X */
- X puts (EXTRACT);
- X puts ("# This is a shell archive, meaning:");
- X printf ("# 1. Remove everything above the %s line.\n", EXTRACT);
- X puts ("# 2. Save the resulting text in a file.");
- X puts ("# 3. Execute the file with /bin/sh (not csh) to create the files:");
- X for (i = optind; i < argc; i++)
- X printf ("#\t%s\n", argv[i]);
- X (void) time (&clock);
- X printf ("# This archive created: %s", ctime (&clock));
- X if (NAME)
- X printf ("# By:\t%s (%s)\n", NAME, ORG ? ORG : "");
- X printf ("export PATH; PATH=%s\n", PATH);
- X return (0);
- X }
- X
- Xfooter ()
- X {
- X puts ("#\tEnd of shell archive");
- X puts ("exit 0");
- X }
- X
- Xarchive (input, output)
- Xchar *input, *output;
- X {
- X char buf[BUFSIZ];
- X FILE *ioptr;
- X if (ioptr = fopen (input, "r"))
- X {
- X if (Count == true)
- X {
- X Ctrlcount = 0; /* no bad control characters so far */
- X Lastchar = '\n'; /* simulate line start */
- X }
- X printf ("%s << \\%s > '%s'\n", Filter, Delim, output);
- X if (Prefix)
- X {
- X while (fgets (buf, BUFSIZ, ioptr))
- X {
- X if (Prefix) outline (Prefix);
- X outline (buf);
- X }
- X }
- X else copyout (ioptr);
- X /* thanks to H. Morrow Long (ittvax!long) for the next fix */
- X if (Lastchar != '\n') /* incomplete last line */
- X putchar ('\n'); /* Delim MUST begin new line! */
- X puts (Delim);
- X if (Count == true && Lastchar != '\n')
- X printf ("%s: a missing newline was added to \"'%s'\"\n", ECHO, input);
- X if (Count == true && Ctrlcount)
- X printf ("%s: %d control character%s may be missing from \"'%s'\"\n",
- X ECHO, Ctrlcount, Ctrlcount > 1 ? "s" : "", input);
- X (void) fclose (ioptr);
- X return (0);
- X }
- X else
- X {
- X fprintf (stderr, "shar: Can't open '%s'\n", input);
- X return (1);
- X }
- X }
- X
- X/*
- X Copyout copies its ioptr almost as fast as possible
- X except that it has to keep track of the last character
- X printed. If the last character is not a newline, then
- X shar has to add one so that the end of file delimiter
- X is recognized by the shell. This checking costs about
- X a 10% difference in user time. Otherwise, it is about
- X as fast as cat. It also might count control characters.
- X*/
- X#define badctrl(c) (iscntrl (c) && !isspace (c))
- Xcopyout (ioptr)
- Xregister FILE *ioptr;
- X {
- X register int C;
- X register int L;
- X register count;
- X count = Count;
- X while ((C = getc (ioptr)) != EOF)
- X {
- X if (count == true && badctrl (C)) Ctrlcount++;
- X L = putchar (C);
- X }
- X Lastchar = L;
- X }
- X
- Xoutline (s)
- Xregister char *s;
- X {
- X if (*s)
- X {
- X while (*s)
- X {
- X if (Count == true && badctrl (*s)) Ctrlcount++;
- X putchar (*s++);
- X }
- X Lastchar = *(s-1);
- X }
- X }
- X
- X#define FSIZE statbuf.st_size
- Xshar (file, type, pos)
- Xchar *file; /* file or directory to be processed */
- Xint type; /* either 'f' for file or 'd' for directory */
- Xint pos; /* 0 going in to a file or dir, 1 going out */
- X {
- X struct stat statbuf;
- X char *basefile = file;
- X if (!strcmp (file, ".")) return;
- X if (stat (file, &statbuf)) FSIZE = 0;
- X if (Basename == true)
- X {
- X while (*basefile) basefile++; /* go to end of name */
- X while (basefile > file && *(basefile-1) != '/') basefile--;
- X }
- X if (pos == 0) /* before the file starts */
- X {
- X if (type == 'd')
- X {
- X printf ("if %s ! -d '%s'\n", TEST, basefile);
- X printf ("then\n");
- X if (Verbose == true)
- X printf (" %s: creating directory \"'%s'\"\n", ECHO, basefile);
- X printf (" %s '%s'\n", MKDIR, basefile);
- X printf ("fi\n");
- X if (Verbose == true)
- X printf ("%s: entering directory \"'%s'\"\n", ECHO, basefile);
- X printf ("%s '%s'\n", CHDIR, basefile);
- X }
- X else /* type == 'f' */
- X {
- X if (Verbose == true)
- X printf ("%s: extracting \"'%s'\" '(%d character%s)'\n",
- X ECHO, basefile, FSIZE, FSIZE > 1 ? "s" : "");
- X if (Silent == false) /* this solution by G|ran Uddeborg */
- X {
- X printf ("if %s -f '%s'\n", TEST, basefile);
- X puts ("then");
- X printf (" %s: will not over-write existing file \"'%s'\"\n",
- X ECHO, basefile);
- X puts ("else");
- X }
- X if (archive (file, basefile)) exit (-1);
- X }
- X }
- X else /* pos == 1, after the file is archived */
- X {
- X if (type == 'd')
- X {
- X if (Verbose == true)
- X printf ("%s: done with directory \"'%s'\"\n", ECHO, basefile);
- X printf ("%s ..\n", CHDIR);
- X }
- X else /* type == 'f' (plain file) */
- X {
- X if (Count == true)
- X {
- X printf ("if %s %d -ne \"`%s '%s'`\"\n",
- X TEST, FSIZE, WC_C, basefile);
- X puts ("then");
- X printf (" %s: error transmitting \"'%s'\" ", ECHO, basefile);
- X printf ("'(should have been %d character%s)'\n",
- X FSIZE, FSIZE > 1 ? "s" : "");
- X puts ("fi");
- X }
- X if (access (file, 1) == 0) /* executable -> chmod +x */
- X printf ("%s '%s'\n", CHMOD, basefile);
- X if (Silent == false)
- X {
- X puts ("fi # end of overwriting check");
- X }
- X }
- X }
- X }
- SHAR_EOF
- if test 8881 -ne "`wc -c < 'shar.c'`"
- then
- echo shar: error transmitting "'shar.c'" '(should have been 8881 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'traverse.3'" '(1169 characters)'
- if test -f 'traverse.3'
- then
- echo shar: will not over-write existing file "'traverse.3'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'traverse.3'
- X.TH TRAVERSE 3WI "December 16, 1984"
- X.SH NAME
- Xtraverse \- recursively traverse a directory
- X.SH SYNOPSIS
- X.nf
- Xtraverse (path, func)
- Xchar *path;
- Xint (*func) ();
- X
- Xfunc (path, filetype, position)
- Xchar *path;
- X.fi
- X.SH DESCRIPTION
- Xtraverse
- Xapplies its argument function func to its argument file pathname path.
- XIf path is a directory,
- Xthen traverse applies func to all its entries.
- XThis traversal is in depth first order
- Xso that files are processed in the order
- Xthat they are stored in the directory.
- X.PP
- XThe argument func should take three parameters:
- Xa file name,
- Xa file type,
- Xand a position.
- XThe call looks like this for directories:
- X.ce
- X(*func) (path, 'd', position);
- Xand like this for other files:
- X.ce
- X(*func) (path, 'f', position);
- XThe position
- Xis 0 when path is first encountered
- Xand 1 when traverse is done.
- XThis is used to allow processing before and after
- Xa directory is processed.
- X.SH EXAMPLE
- X.nf
- Xlist (name, type, pos)
- Xchar *name;
- X {
- X if (type == 'd')
- X printf ("%s %s\en", pos ? "Leaving" : "Entering", name);
- X else /* type == 'f' */
- X printf (" %s\en", name);
- X }
- X.fi
- X.SH AUTHOR
- XGary Perlman
- X.SH BUGS
- XThere are no diagnostics when directories cannot be searched.
- SHAR_EOF
- if test 1169 -ne "`wc -c < 'traverse.3'`"
- then
- echo shar: error transmitting "'traverse.3'" '(should have been 1169 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'traverse.c'" '(1769 characters)'
- if test -f 'traverse.c'
- then
- echo shar: will not over-write existing file "'traverse.c'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'traverse.c'
- X/*LINTLIBRARY*/
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X
- X#ifdef MAXNAMLEN
- X
- X#define namedir(entry) (entry->d_name)
- X#define MAXNAME 256
- X
- X#else
- X
- X#define DIR FILE
- X#define MAXNAME (DIRSIZ+2)
- X#define opendir(path) fopen (path, "r")
- X#define closedir(dirp) fclose (dirp)
- Xstruct direct *
- Xreaddir (dirp)
- XDIR *dirp;
- X {
- X static struct direct entry;
- X if (dirp == NULL) return (NULL);
- X for (;;)
- X {
- X if (fread (&entry, sizeof (struct direct), 1, dirp) == 0) return (NULL);
- X if (entry.d_ino) return (&entry);
- X }
- X }
- Xchar *strncpy ();
- Xchar *
- Xnamedir (entry)
- Xstruct direct *entry;
- X {
- X static char name[MAXNAME];
- X return (strncpy (name, entry->d_name, DIRSIZ));
- X }
- X
- X#endif
- X
- X#include <sys/stat.h>
- X#define isdir(path) (stat(path, &buf) ? 0 : (buf.st_mode&S_IFMT)==S_IFDIR)
- X
- Xtraverse (path, func)
- Xchar *path;
- Xint (*func) ();
- X {
- X DIR *dirp;
- X struct direct *entry;
- X struct stat buf;
- X int filetype = isdir (path) ? 'd' : 'f';
- X (*func) (path, filetype, 0);
- X if (filetype == 'd')
- X {
- X if (chdir (path) == 0)
- X {
- X if (dirp = opendir ("."))
- X {
- X while (entry = readdir (dirp))
- X {
- X char name[MAXNAME];
- X (void) strcpy (name, namedir (entry));
- X if (strcmp(name, ".") && strcmp(name, ".."))
- X traverse (name, func);
- X }
- X (void) closedir(dirp);
- X }
- X (void) chdir ("..");
- X }
- X }
- X (*func) (path, filetype, 1);
- X }
- X
- X#ifdef STANDALONE
- X
- Xstatic Indent = 0;
- Xtryverse (file, type, pos)
- Xchar *file;
- X {
- X int in;
- X if (pos == 0)
- X {
- X for (in = 0; in < Indent; in++) putchar ('\t');
- X if (type == 'd')
- X {
- X printf ("%s/\n", file);
- X Indent++;
- X }
- X else puts (file);
- X }
- X else if (type == 'd') Indent--;
- X }
- X
- Xmain (argc, argv) char **argv;
- X {
- X int tryverse ();
- X char *root = argc > 1 ? argv[1] : ".";
- X traverse (root, tryverse);
- X }
- X#endif
- SHAR_EOF
- if test 1769 -ne "`wc -c < 'traverse.c'`"
- then
- echo shar: error transmitting "'traverse.c'" '(should have been 1769 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'getopt.3'" '(2755 characters)'
- if test -f 'getopt.3'
- then
- echo shar: will not over-write existing file "'getopt.3'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'getopt.3'
- X.TH GETOPT 3 local
- X.DA 25 March 1982
- X.SH NAME
- Xgetopt \- get option letter from argv
- X.SH SYNOPSIS
- X.ft B
- Xint getopt(argc, argv, optstring)
- X.br
- Xint argc;
- X.br
- Xchar **argv;
- X.br
- Xchar *optstring;
- X.sp
- Xextern char *optarg;
- X.br
- Xextern int optind;
- X.ft
- X.SH DESCRIPTION
- X.I Getopt
- Xreturns the next option letter in
- X.I argv
- Xthat matches a letter in
- X.IR optstring .
- X.I Optstring
- Xis a string of recognized option letters;
- Xif a letter is followed by a colon, the option is expected to have
- Xan argument that may or may not be separated from it by white space.
- X.I Optarg
- Xis set to point to the start of the option argument on return from
- X.IR getopt .
- X.PP
- X.I Getopt
- Xplaces in
- X.I optind
- Xthe
- X.I argv
- Xindex of the next argument to be processed.
- XBecause
- X.I optind
- Xis external, it is normally initialized to zero automatically
- Xbefore the first call to
- X.IR getopt .
- X.PP
- XWhen all options have been processed (i.e., up to the first
- Xnon-option argument),
- X.I getopt
- Xreturns
- X.BR EOF .
- XThe special option
- X.B \-\-
- Xmay be used to delimit the end of the options;
- X.B EOF
- Xwill be returned, and
- X.B \-\-
- Xwill be skipped.
- X.SH SEE ALSO
- Xgetopt(1)
- X.SH DIAGNOSTICS
- X.I Getopt
- Xprints an error message on
- X.I stderr
- Xand returns a question mark
- X.RB ( ? )
- Xwhen it encounters an option letter not included in
- X.IR optstring .
- X.SH EXAMPLE
- XThe following code fragment shows how one might process the arguments
- Xfor a command that can take the mutually exclusive options
- X.B a
- Xand
- X.BR b ,
- Xand the options
- X.B f
- Xand
- X.BR o ,
- Xboth of which require arguments:
- X.PP
- X.RS
- X.nf
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int c;
- X extern int optind;
- X extern char *optarg;
- X \&.
- X \&.
- X \&.
- X while ((c = getopt(argc, argv, "abf:o:")) != EOF)
- X switch (c) {
- X case 'a':
- X if (bflg)
- X errflg++;
- X else
- X aflg++;
- X break;
- X case 'b':
- X if (aflg)
- X errflg++;
- X else
- X bproc();
- X break;
- X case 'f':
- X ifile = optarg;
- X break;
- X case 'o':
- X ofile = optarg;
- X break;
- X case '?':
- X default:
- X errflg++;
- X break;
- X }
- X if (errflg) {
- X fprintf(stderr, "Usage: ...");
- X exit(2);
- X }
- X for (; optind < argc; optind++) {
- X \&.
- X \&.
- X \&.
- X }
- X \&.
- X \&.
- X \&.
- X}
- X.RE
- X.PP
- XA template similar to this can be found in
- X.IR /usr/pub/template.c .
- X.SH HISTORY
- XWritten by Henry Spencer, working from a Bell Labs manual page.
- XBehavior believed identical to the Bell version.
- X.SH BUGS
- XIt is not obvious how
- X`\-'
- Xstanding alone should be treated; this version treats it as
- Xa non-option argument, which is not always right.
- X.PP
- XOption arguments are allowed to begin with `\-';
- Xthis is reasonable but reduces the amount of error checking possible.
- X.PP
- X.I Getopt
- Xis quite flexible but the obvious price must be paid: there is much
- Xit could do that it doesn't, like
- Xchecking mutually exclusive options, checking type of
- Xoption arguments, etc.
- SHAR_EOF
- if test 2755 -ne "`wc -c < 'getopt.3'`"
- then
- echo shar: error transmitting "'getopt.3'" '(should have been 2755 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'getopt.c'" '(1437 characters)'
- if test -f 'getopt.c'
- then
- echo shar: will not over-write existing file "'getopt.c'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'getopt.c'
- X/* got this off net.sources */
- X#include <stdio.h>
- X
- X/*
- X * get option letter from argument vector
- X */
- Xint opterr = 1, /* useless, never set or used */
- X optind = 1, /* index into parent argv vector */
- X optopt; /* character checked for validity */
- Xchar *optarg; /* argument associated with option */
- X
- X#define BADCH (int)'?'
- X#define EMSG ""
- X#define tell(s) fputs(*nargv,stderr);fputs(s,stderr); \
- X fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
- X
- Xgetopt(nargc,nargv,ostr)
- Xint nargc;
- Xchar **nargv,
- X *ostr;
- X{
- X static char *place = EMSG; /* option letter processing */
- X register char *oli; /* option letter list index */
- X char *index();
- X
- X if(!*place) { /* update scanning pointer */
- X if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
- X if (*place == '-') { /* found "--" */
- X ++optind;
- X return(EOF);
- X }
- X } /* option letter okay? */
- X if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
- X if(!*place) ++optind;
- X tell(": illegal option -- ");
- X }
- X if (*++oli != ':') { /* don't need argument */
- X optarg = NULL;
- X if (!*place) ++optind;
- X }
- X else { /* need an argument */
- X if (*place) optarg = place; /* no white space */
- X else if (nargc <= ++optind) { /* no arg */
- X place = EMSG;
- X tell(": option requires an argument -- ");
- X }
- X else optarg = nargv[optind]; /* white space */
- X place = EMSG;
- X ++optind;
- X }
- X return(optopt); /* dump back option letter */
- X}
- SHAR_EOF
- if test 1437 -ne "`wc -c < 'getopt.c'`"
- then
- echo shar: error transmitting "'getopt.c'" '(should have been 1437 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'Makefile'" '(142 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'Makefile'
- XCFLAGS=-O
- Xshar: shar.o traverse.o getopt.o
- X cc $(CFLAGS) -o shar shar.o traverse.o getopt.o
- Xtraverse:
- X cc -o traverse -DSTANDALONE traverse.c
- SHAR_EOF
- if test 142 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 142 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-